package com.nbsaas.boot.product.ext.resource;

import com.nbsaas.boot.product.api.apis.ProductApi;
import com.nbsaas.boot.product.api.apis.ProductSkuApi;
import com.nbsaas.boot.product.api.domain.request.ProductRequest;
import com.nbsaas.boot.product.api.domain.request.ProductSkuRequest;
import com.nbsaas.boot.product.api.domain.response.ProductResponse;
import com.nbsaas.boot.product.ext.apis.ProductExtApi;
import com.nbsaas.boot.product.ext.domain.request.ProductExtRequest;
import com.nbsaas.boot.product.ext.domain.response.ProductExtResponse;
import com.nbsaas.boot.rest.enums.StoreState;
import com.nbsaas.boot.rest.filter.Filter;
import com.nbsaas.boot.rest.response.ResponseObject;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Optional;


@Service
public class ProductExtResource implements ProductExtApi {

    @Resource
    private ProductApi productApi;

    @Resource
    private ProductSkuApi productSkuApi;

    @Transactional
    @Override
    public ResponseObject<ProductResponse> create(ProductExtRequest request) {
        request.setStoreState(StoreState.normal);
        ResponseObject<ProductResponse> result = new ResponseObject<>();
        if (request.getSkus() != null && !request.getSkus().isEmpty()) {
            long num = request.getSkus().stream().filter(item -> item.getPrice() == null).count();
            if (num > 0) {
                result.setCode(500);
                result.setMsg("sku价格不能为空");
                return result;
            }

            checkPrice(request);
        } else {
            request.setMinPrice(request.getPrice());
            request.setMaxPrice(request.getPrice());
        }

        ProductResponse res = productApi.createData(request);
        if (request.getSkus() != null && !request.getSkus().isEmpty()) {
            request.getSkus().forEach(item -> {
                item.setProduct(res.getId());
                productSkuApi.createData(item);
            });
        }

        return result;
    }

    private static void checkPrice(ProductExtRequest request) {
        Optional<BigDecimal> minPrice = request.getSkus().stream().map(ProductSkuRequest::getPrice).min(BigDecimal::compareTo);
        minPrice.ifPresent(request::setMinPrice);

        Optional<BigDecimal> maxPrice = request.getSkus().stream().map(ProductSkuRequest::getPrice).max(BigDecimal::compareTo);
        maxPrice.ifPresent(request::setMaxPrice);


        Long stockNum = request.getSkus().stream().map(item -> item.getStockNum() != null ? item.getStockNum() : 0).reduce(0L, Long::sum);
        request.setStockNum(stockNum);
    }

    @Transactional
    @Override
    public ResponseObject<ProductResponse> update(ProductExtRequest request) {
        ResponseObject<ProductResponse> result = new ResponseObject<>();
        if (request.getSkus() != null && !request.getSkus().isEmpty()) {
            long num = request.getSkus().stream().filter(item -> item.getPrice() == null).count();
            if (num > 0) {
                result.setCode(500);
                result.setMsg("sku价格不能为空");
                return result;
            }
            checkPrice(request);
        } else {
            request.setMinPrice(request.getPrice());
            request.setMaxPrice(request.getPrice());
        }

        productApi.update(request);
        productSkuApi.deleteByFilter(Filter.eq("product.id", request.getId()));
        if (request.getSkus() != null && !request.getSkus().isEmpty()) {
            request.getSkus().forEach(item -> {
                item.setProduct(request.getId());
                productSkuApi.createData(item);
            });
        }

        return result;
    }

    @Override
    public ResponseObject<ProductExtResponse> view(ProductRequest request) {
        ResponseObject<ProductExtResponse> result=new ResponseObject<>();
        ResponseObject<ProductResponse> res = productApi.view(request);
        if (res.getCode()!=200){
            result.setCode(res.getCode());
            result.setMsg(res.getMsg());
            return result;
        }
        ProductExtResponse ext=new ProductExtResponse();
        BeanUtils.copyProperties(res.getData(),ext);
        ext.setSkus(productSkuApi.listData(Filter.eq("product.id", request.getId())));
        result.setData(ext);
        return result;
    }
}
